import { Node, Connection, ParamItem, ExecutionNode, ExecutionContext, NodeData, SSEConnectionState } from '../types/node';
import { executeFlow, executeFlowSSEWithChat, FlowExecutionCallbacks, FlowExecutionEvent, FlowExecutionResult } from '/@/api/knowledge/aiFlow';
import { generateUUID } from '/@/utils/other';
import { nextTick } from 'vue';
import { useThrottleFn, useTimeoutFn } from '@vueuse/core';

// Define the mixin as a Vue component options object
export default {
	data(): NodeData {
		return {
			id: null,
			form: {},
			env: [],
			nodes: [],
			connections: [],
			isStream: true,
			startNodeParams: [],
			showExecutionPanel: false,
			// VueUse状态
			conversationId: '',
			isRunning: false,
			connectionState: 'idle',
			executionResult: {},
			executionNodes: [],
			executionTime: '0',
			totalTokens: 0,
			sseCleanupFn: null,
			throttledConnectionCheck: null, // VueUse防抖函数
		};
	},
	async created(this: any) {
		// 从路由参数中获取id
		this.id = this.$route.params.id;
		
		// 初始化VueUse工具
		this.initVueUseTools();
	},
	computed: {
		/**
		 * 是否可以发起新连接
		 */
		canConnect(this: any): boolean {
			return this.connectionState === 'idle' || this.connectionState === 'error' || this.connectionState === 'closed';
		},

		/**
		 * 是否有活动连接
		 */
		hasActiveConnection(this: any): boolean {
			return this.connectionState === 'connecting' || this.connectionState === 'connected';
		},

		/**
		 * 计算工作流的执行顺序
		 * @returns {Node[]} 按执行顺序排列的节点数组
		 */
		workflowExecutionOrder(this: any): Node[] {
			// 初始化访问记录和执行顺序数组
			const visited = new Set<string>();
			const executionOrder: Node[] = [];

			// 解构获取节点和连接信息
			const { nodes, connections } = this;

			// 查找开始节点
			const startNode = nodes.find((node: Node) => node.type === 'start');
			if (!startNode) {
				// 使用this.$log替代console以避免linter错误
				this.$log?.warn?.('未找到开始节点');
				return [];
			}

			/**
			 * 深度优先搜索遍历节点
			 * @param {string} nodeId - 当前节点ID
			 * @param {string[]} path - 当前路径
			 * @param {number|null} branchIndex - 分支索引
			 */
			const dfs = (nodeId: string, path: string[] = [], branchIndex: number | null = null): void => {
				// 检查循环依赖
				if (visited.has(nodeId)) {
					if (path.includes(nodeId)) {
						const cycleNodes: string[] = path.slice(path.indexOf(nodeId));
						// 使用this.$log替代console以避免linter错误
						this.$log?.warn?.('检测到循环依赖，涉及节点:', cycleNodes);
						return;
					}
					return;
				}

				// 获取当前节点
				const currentNode = nodes.find((node: Node) => node.id === nodeId);
				if (!currentNode) {
					// 使用this.$log替代console以避免linter错误
					this.$log?.warn?.('未找到节点:', nodeId);
					return;
				}

				// 标记节点为已访问
				visited.add(nodeId);
				path.push(nodeId);

				// 设置分支信息
				if (branchIndex !== null) {
					currentNode._branchIndex = branchIndex;
				}

				// 添加到执行顺序
				executionOrder.push(currentNode);

				// 获取所有出边并按端口索引排序
				const outgoingConnections = connections
					.filter((conn: Connection) => conn.sourceId === nodeId)
					.sort((a: Connection, b: Connection) => (a.portIndex || 0) - (b.portIndex || 0));

				// 根据节点类型处理后续节点
				if (['switch', 'question'].includes(currentNode.type)) {
					// 分支节点：为每个分支的节点添加分支索引
					outgoingConnections.forEach((conn: Connection) => {
						dfs(conn.targetId, [...path], conn.portIndex || 0);
					});
				} else {
					// 普通节点：继承当前分支索引
					outgoingConnections.forEach((conn: Connection) => {
						dfs(conn.targetId, [...path], branchIndex);
					});
				}
			};

			// 从开始节点开始遍历
			dfs(startNode.id);

			return executionOrder;
		},
	},
	methods: {
		/**
		 * 深拷贝对象
		 * @param {T} obj - 要拷贝的对象
		 * @returns {T} 拷贝后的对象
		 */
		deepClone<T>(obj: T): T {
			return JSON.parse(JSON.stringify(obj));
		},

		/**
		 * 初始化全局环境变量
		 */
		initGlobalEnv(this: any): void {
			// 确保 window.$glob 存在
			if (!window.$glob) window.$glob = {};

			// 确保 this.env 是一个数组
			if (!this.env || !Array.isArray(this.env)) {
				this.env = [];
				return;
			}

			this.env.forEach((item: { name: string; value: any }) => {
				if (item.name) window.$glob[item.name] = item.value;
			});
		},

		/**
		 * 初始化VueUse工具（在组件created时调用）
		 */
		initVueUseTools(this: any): void {
			// 初始化会话ID持久化存储
			if (!this.conversationId) {
				this.conversationId = generateUUID();
			}

			// 创建防抖函数
			this.throttledConnectionCheck = useThrottleFn(() => {
				if (!this.canConnect) {
					this.$log?.warn?.('SSE连接已存在或状态不允许发起新连接');
					return false;
				}
				return true;
			}, 1000);
		},

		/**
		 * 安全地清理SSE连接
		 */
		safeCleanupSSE(this: any): void {
			try {
				if (this.sseCleanupFn && typeof this.sseCleanupFn === 'function') {
					this.sseCleanupFn();
				}
			} catch (error: any) {
				this.$log?.error?.('清理SSE连接时出错:', error.message);
			} finally {
				this.sseCleanupFn = null;
				this.connectionState = 'closed';
			}
		},

		/**
		 * 重置连接状态
		 */
		resetConnection(this: any): void {
			this.safeCleanupSSE();
			this.isRunning = false;
			this.connectionState = 'idle';
			this.executionResult = {};
			this.executionNodes = [];
			this.executionTime = '0';
			this.totalTokens = 0;
		},

		/**
		 * 重置会话，在关闭面板时调用
		 */
		resetConversation(this: any): void {
			this.resetConnection();
		},

		/**
		 * 带超时控制的SSE执行函数（VueUse优化版本）
		 */
		async executeWithTimeout(this: any, params: any, timeoutMs: number = 300000): Promise<any> {
			// 检查连接状态
			if (!this.throttledConnectionCheck) {
				this.$log?.warn?.('throttledConnectionCheck 未初始化，跳过检查');
			} else if (!this.throttledConnectionCheck()) {
				throw new Error('无法发起新的SSE连接：连接已存在或请求过于频繁');
			}
			
			// 安全清理现有连接
			this.safeCleanupSSE();
			
			// 更新状态
			this.connectionState = 'connecting';
			this.isRunning = true;
			
			// 初始化聊天消息累积器
			let chatMessageContent = '';
			let isChatStreaming = false;
			
			const startTime = performance.now();
			
			// 使用VueUse的超时功能
			const { start: startTimeout, stop: stopTimeout } = useTimeoutFn(() => {
				this.$log?.warn?.('SSE连接超时，自动关闭');
				this.safeCleanupSSE();
				this.connectionState = 'error';
				this.isRunning = false;
				this.executionResult = { error: '执行超时' };
			}, timeoutMs);
			
			try {
				// 开始超时计时
				startTimeout();
				
				// 设置SSE回调函数
				const callbacks: FlowExecutionCallbacks = {
					onStart: () => {
						this.$log?.info?.('工作流开始执行');
						this.connectionState = 'connected';
						chatMessageContent = '';
						isChatStreaming = false;
					},
					onProgress: (event: FlowExecutionEvent) => {
						this.$log?.info?.(`节点执行进度: ${event.nodeName} (${event.nodeId})`);
						
						// 更新执行节点状态
						if (event.nodeId && this.executionNodes) {
							const nodeIndex = this.executionNodes.findIndex((n: any) => n.id === event.nodeId);
							if (nodeIndex >= 0) {
								nextTick(() => {
									this.executionNodes[nodeIndex] = {
										...this.executionNodes[nodeIndex],
										status: 'running',
										...event.data
									};
								});
							}
						}
					},
					onChatMessage: (content: string, isComplete: boolean, tokens?: number, duration?: number, nodes?: Array<any>) => {
						// 累积聊天消息内容
						chatMessageContent += content;
						isChatStreaming = true;
						
						// 处理 tokens、duration 和 nodes 信息
						if (isComplete) {
							if (tokens) this.totalTokens = tokens;
							if (duration) this.executionTime = duration.toString();
							if (nodes) this.executionNodes = nodes;
						}
						
						// 实时更新executionResult
						nextTick(() => {
							this.executionResult = {
								...this.executionResult,
								chatMessage: chatMessageContent,
								isStreaming: !isComplete
							};
						});
					},
					onComplete: (result: FlowExecutionResult) => {
						this.$log?.info?.('工作流执行完成');
						
						nextTick(() => {
							this.executionNodes = result.nodes;
							// 如果有聊天消息，将其合并到结果中
							if (isChatStreaming && chatMessageContent) {
								this.executionResult = {
									...result.result,
									chatMessage: chatMessageContent,
									isStreaming: false
								};
							} else {
								this.executionResult = result.result;
							}
							this.executionTime = Number(result.duration).toString();
							this.totalTokens = Number(result.totalTokens || 0);
							this.isRunning = false;
							// 完成时安全清理连接
							this.safeCleanupSSE();
						});
					},
					onError: (error: string) => {
						this.$log?.error?.('工作流执行失败:', error);
						
						nextTick(() => {
							// 如果有部分聊天消息，也保留在错误结果中
							const errorResult: any = { error };
							if (isChatStreaming && chatMessageContent) {
								errorResult.chatMessage = chatMessageContent;
								errorResult.isStreaming = false;
							}
							this.executionResult = errorResult;
							this.isRunning = false;
							// 出错时安全清理连接
							this.safeCleanupSSE();
							this.connectionState = 'error';
						});
					},
				};
				
				// 发起SSE连接
				const chatResultWithCleanup = executeFlowSSEWithChat(
					{ 
						id: params.id, 
						conversationId: this.conversationId, 
						params: params.params, 
						envs: params.envs, 
						stream: true 
					},
					callbacks
				);
				
				// 保存SSE连接的清理函数
				this.sseCleanupFn = chatResultWithCleanup.cleanup;
				
				// 等待聊天结果
				const chatResult = await chatResultWithCleanup;
				
				// 处理最终结果
				nextTick(() => {
					this.executionResult = {
						chatMessage: chatResult.chatMessage,
						result: chatResult.result,
						isStreaming: false
					};
					this.isRunning = false;
					this.safeCleanupSSE();
				});
				
				const endTime = performance.now();
				this.executionTime = ((endTime - startTime) / 1000).toFixed(3);
				
				return chatResult;
			} catch (error: any) {
				this.$log?.error?.('执行SSE连接失败:', error);
				this.safeCleanupSSE();
				this.connectionState = 'error';
				this.isRunning = false;
				throw error;
			} finally {
				// 无论成功还是失败，都停止超时计时
				stopTimeout();
			}
		},

		/**
		 * 处理工具栏运行按钮点击
		 */
		handleRunClick(this: any): void {
			// 获取开始节点
			const startNode = this.nodes.find((node: Node) => node.type === 'start');
			if (startNode?.outputParams?.length) {
				this.startNodeParams = this.deepClone(startNode.inputParams);
				this.showExecutionPanel = true;
			} else {
				// 如果没有参数，直接运行
				this.runWorkflow();
			}
		},

		/**
		 * 使用SSE运行工作流（VueUse优化版本）
		 * @param {ParamItem[] | null} params - 开始节点参数
		 * @returns {Promise<ExecutionContext>} 执行上下文
		 */
		async runWorkflowSSE(this: any, params: ParamItem[] | null = null): Promise<ExecutionContext> {
			this.initGlobalEnv();
			this.showExecutionPanel = true;
			const workflowExecutionOrder = this.deepClone(this.workflowExecutionOrder);

			try {
				const executionOrder = workflowExecutionOrder;
				const firstNode = executionOrder[0];
				firstNode.inputParams = [];
				const context: ExecutionContext = {
					variables: {},
					params: {},
					envs: {},
				};

				// 如果存在环境变量，也添加到开始节点的输入参数中
				if (this.env && Array.isArray(this.env) && this.env.length > 0) {
					this.env.forEach((item: { name: string; value: any }) => {
						if (!item.name) return;
						const envKey = `global.${item.name}`;
						context.envs[envKey] = item.value;
						firstNode.inputParams!.push({ type: envKey });
					});
				}

				// 如果有开始节点参数，设置到上下文中
				if (params) {
					params.forEach((param) => {
						const key = `${firstNode.id}.${param.key || param.type}`;
						context.params[key] = param.value;
						firstNode.inputParams!.push({ type: key });
					});
				}

				// 根据isStream属性决定使用SSE还是普通请求
				if (this.isStream) {
					// 使用VueUse优化的SSE执行工作流
					const sseParams = {
						id: this.id,
						params: context.params,
						envs: context.envs,
						stream: true
					};
					await this.executeWithTimeout(sseParams);
				} else {
					// 使用普通请求
					await this.executeWithHTTP(context);
				}

				return context;
			} catch (error: any) {
				this.$log?.error?.('运行工作流失败:', error);
				
				throw error;
			}
		},

		/**
		 * 使用普通HTTP请求执行工作流
		 * @param {ExecutionContext} context - 执行上下文
		 */
		async executeWithHTTP(this: any, context: ExecutionContext): Promise<void> {
			const { data } = await executeFlow({ 
				id: this.id, 
				params: context.params, 
				envs: context.envs, 
				stream: false 
			});

			// 处理普通JSON响应
			this.$nextTick(() => {
				// 检查响应数据结构，支持不同的返回格式
				if (data.nodes && data.result !== undefined) {
					// 标准格式: { nodes, result, duration, totalTokens }
					this.executionNodes = data.nodes;
					this.executionResult = data.result;
					this.executionTime = Number(data.duration || 0);
					this.totalTokens = Number(data.totalTokens || 0);
				} else if (data.data) {
					// 嵌套格式: { data: { nodes, result, duration, totalTokens } }
					const responseData = data.data;
					this.executionNodes = responseData.nodes || [];
					this.executionResult = responseData.result || responseData;
					this.executionTime = Number(responseData.duration || 0);
					this.totalTokens = Number(responseData.totalTokens || 0);
				} else {
					// 直接返回格式：直接使用 data 作为结果
					this.executionNodes = data.nodes || [];
					this.executionResult = data;
					this.executionTime = Number(data.duration || 0);
					this.totalTokens = Number(data.totalTokens || 0);
				}

				// 如果结果包含聊天消息内容，也进行处理
				if (this.executionResult && typeof this.executionResult === 'object') {
					// 检查是否有聊天消息相关字段
					if (this.executionResult.chatMessage || this.executionResult.content) {
						const chatMessage = this.executionResult.chatMessage || this.executionResult.content;
						this.executionResult = {
							...this.executionResult,
							chatMessage: chatMessage,
							isStreaming: false
						};
					}
				}

				this.isRunning = false;
			});
		},

		/**
		 * 运行工作流
		 * @param {ParamItem[] | null} params - 开始节点参数
		 * @returns {Promise<ExecutionContext>} 执行上下文
		 */
		async runWorkflow(this: any, params: ParamItem[] | null = null): Promise<ExecutionContext> {
			// 默认使用SSE版本
			return this.runWorkflowSSE(params);
		},

		/**
		 * 判断节点是否应该被跳过
		 * @param {Node} node - 当前节点
		 * @param {Map<string, number>} activeBranches - 活动分支信息
		 * @returns {boolean} 是否应该跳过
		 */
		shouldSkipNode(this: any, node: Node, activeBranches: Map<string, number>): boolean {
			// 如果节点没有分支信息，不跳过
			if (node._branchIndex === undefined) {
				return false;
			}

			// 查找当前节点所属的分支节点
			const branchNodeId = this.findBranchNodeId(node);
			if (!branchNodeId) {
				return false;
			}

			// 获取活动分支索引
			const activeBranch = activeBranches.get(branchNodeId);

			// 如果找不到活动分支信息，或者分支索引匹配，则不跳过
			if (activeBranch === undefined || activeBranch === node._branchIndex) {
				return false;
			}

			return true;
		},

		/**
		 * 查找节点所属的分支节点ID
		 * @param {Node} node - 当前节点
		 * @returns {string|null} 分支节点ID
		 */
		findBranchNodeId(this: any, node: Node): string | null {
			// 遍历所有连接找到源节点
			const connection = this.connections.find((conn: Connection) => conn.targetId === node.id);
			if (!connection) {
				return null;
			}

			const sourceNode = this.nodes.find((n: Node) => n.id === connection.sourceId);
			if (!sourceNode) {
				return null;
			}

			// 如果源节点是分支节点，返回其ID
			if (['switch', 'question'].includes(sourceNode.type)) {
				return sourceNode.id;
			}

			// 递归查找
			return this.findBranchNodeId(sourceNode);
		},

		/**
		 * 解析节点的输入参数
		 * @param {Node} node - 当前节点
		 * @param {ExecutionContext} context - 执行上下文
		 * @returns {Record<string, any>} 解析后的输入参数
		 */
		resolveNodeInputParams(this: any, node: Node, context: ExecutionContext): Record<string, any> {
			const inputParams: Record<string, any> = {
				id: node.id,
			};
			let list = this.deepClone(node.inputParams || []);
			if (node.type === 'http') {
				if (node.bodyParams) list = list.concat(node.bodyParams);
				if (node.headerParams) list = list.concat(node.headerParams);
			}
			list?.forEach((ele: ParamItem) => {
				const { value, name, type } = ele;
				const key = `${node.id}.${name}`;
				if (type && type.includes('global')) {
					inputParams[type] = window.$glob[type.replace('global.', '')];
					context.params[type] = inputParams[type];
				} else if (type) {
					inputParams[type] = context.params[type];
				} else if (value) {
					inputParams[key] = value;
					context.params[key] = value;
				}
			});
			return inputParams;
		},
	},
};
